package com.party.mobile.biz.sign;

import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.common.paging.Page;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.common.utils.PartyCode;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.YesNoStatus;
import com.party.core.model.sign.*;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.sign.ISignApplyService;
import com.party.core.service.sign.ISignGroupService;
import com.party.core.service.sign.ISignProjectService;
import com.party.core.service.sign.ISignRecordService;
import com.party.core.utils.MyBeanUtils;
import com.party.mobile.biz.file.FileBizService;
import com.party.mobile.web.dto.login.output.CurrentUser;
import com.party.mobile.web.dto.sign.output.ApplyDetailOutput;
import com.party.mobile.web.dto.sign.output.SignGroupListOutput;
import com.party.mobile.web.dto.sign.output.SignProjectListOutput;
import com.party.mobile.web.dto.sign.output.SignProjectOutput;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 签到项目业务接口
 * Created by wei.li
 *
 * @date 2017/6/8 0008
 * @time 18:24
 */

@Service
public class SignProjectBizService {

    @Autowired
    private ISignProjectService signProjectService;

    @Autowired
    private ISignApplyService signApplyService;

    @Autowired
    private ISignGroupService signGroupService;

    @Autowired
    private ISignRecordService signRecordService;

    @Autowired
    private CosBizService cosBizService;

    @Autowired
    private FileBizService fileBizService;

    @Autowired
    private IMemberGroupService memberGroupService;

    /**
     * 获取签到项目信息
     * @param id 项目编号
     * @param currentUser 当前用户
     * @return 签到项目
     */
    public SignProjectOutput get(String id, CurrentUser currentUser){

        SignProjectAuthor signProjectAuthor = signProjectService.getProjectAuthor(id);
        if (null == signProjectAuthor){
            throw new BusinessException(PartyCode.IS_NO_DATA, "签到项目不存在");
        }
        SignProjectOutput signProjectOutput = SignProjectOutput.transform(signProjectAuthor);
        if (Strings.isNullOrEmpty(signProjectAuthor.getPublisher())){
            signProjectOutput.setPublisher(signProjectAuthor.getAuthorName());
            signProjectOutput.setPublisherLogo(signProjectAuthor.getAuthorLogo());
        }

        if (null != currentUser){
            //是否报名
            GroupMember groupMember = signApplyService.get(currentUser.getId(), id);
            if (null == groupMember){
                signProjectOutput.setApply(false);
            }
            else {
                signProjectOutput.setApply(true);
                signProjectOutput.setApplyStatus(groupMember.getStatus());
                signProjectOutput.setApplyId(groupMember.getId());

                //今天是否签到
                SignRecord signRecord = signRecordService.getToday(groupMember.getId());
                if (null != signRecord){
                    signProjectOutput.setSign(true);
                }
            }

        }
        else {
            signProjectOutput.setApply(false);
        }

        //是否在有效时间内
        Date now = new Date();
        if (DateUtils.compareDate(now, signProjectAuthor.getStartTime()) == 1
                && DateUtils.compareDate(signProjectAuthor.getEndTime(), now) == 1){
            signProjectOutput.setValidTime(true);
        }
        return signProjectOutput;
    }

    /**
     * 获取一周运动数据
     * @param projectId 项目id
     * @return
     */
    public List<Map<String, Object>> getOneWeekSignData(String projectId, String memberId) {
        GroupMember groupMember = signApplyService.get(memberId, projectId);

        // 一周数据
        List<Date> dayOfWeeks = this.getWeekdays();
        List<Map<String, Object>> weekDatas = Lists.newArrayList();
        for (Date day : dayOfWeeks) {
            Map<String, Object> data = Maps.newHashMap();
            data.put("day", day);
            if (groupMember == null || day.getTime() > System.currentTimeMillis()) { // 没有打卡或者大于今天的
                data.put("isSign", false);
            } else {
                Boolean isSign = signRecordService.isSignByDay(groupMember.getId(), day);
                data.put("isSign", isSign);
            }
            weekDatas.add(data);
        }
        return weekDatas;
    }

    /**
     * 报名详情
     * @param id 编号
     * @return 报名详情
     */
    public ApplyDetailOutput getApplyDetail(String id){
        SignProject signProject = signProjectService.get(id);
        ApplyDetailOutput applyDetailOutput = ApplyDetailOutput.transform(signProject);

        SignGroup signGroup = new SignGroup();
        signGroup.setProjectId(id);
        List<SignGroupListOutput> signGroupList = LangUtils.transform(signGroupService.list(signGroup),
                new Function<SignGroup, SignGroupListOutput>() {
                    @Nullable
                    @Override
                    public SignGroupListOutput apply(@Nullable SignGroup input) {
                        SignGroupListOutput output = new SignGroupListOutput();
                        try {
                            MyBeanUtils.copyBeanNotNull2Bean(input, output);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return output;
                    }
                });
        applyDetailOutput.setSignGroupList(signGroupList);
        return applyDetailOutput;
    }

    /**
     * 我参与的打卡项目
     *
     * @param currentUserId 用户id
     * @param page          分页参数
     * @return 项目集合
     */
    public List<SignProjectListOutput> getMyJoinList(String currentUserId, Page page) {
        SignProject signProject = new SignProject();
        signProject.setCreateBy(currentUserId);
        List<SignProjectAuthor> signProjects = signProjectService.myJoinList(signProject, page);
        List<SignProjectListOutput> listOutputs = LangUtils.transform(signProjects, new Function<SignProjectAuthor, SignProjectListOutput>() {
            @Nullable
            @Override
            public SignProjectListOutput apply(@Nullable SignProjectAuthor input) {
                SignProjectListOutput listOutput = new SignProjectListOutput();
                try {
                    MyBeanUtils.copyBeanNotNull2Bean(input, listOutput);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                listOutput.setApplyNum(input.getApplyNum());

                if (input.getEndTime().getTime() > System.currentTimeMillis()) {
                    if (StringUtils.isNotEmpty(input.getTodayRecordId())) {
                        listOutput.setSignStatus(YesNoStatus.YES.getCode());
                    } else {
                        listOutput.setSignStatus(YesNoStatus.NO_NEW.getCode());
                    }
                } else {
                    listOutput.setSignStatus(3); // 已结束
                }
                String filePath = fileBizService.getUploadCIPath(input.getCreateBy(), "signProject");
                String qrCodeUrl = cosBizService.getPreviewPictureUrl(filePath + input.getId());
                listOutput.setQrCodeUrl(qrCodeUrl);
                return listOutput;
            }
        });
        return listOutputs;
    }

    /**
     * 我参加最新打卡项目
     *
     * @param currentUserId 用户id
     * @param
     * @return 项目集合
     */
    public List<SignProjectListOutput> myJoinProject(String currentUserId) {
        SignProject signProject = new SignProject();
        signProject.setCreateBy(currentUserId);
        List<SignProjectAuthor> signProjects = signProjectService.myJoinProject(signProject);
        List<SignProjectListOutput> listOutputs = LangUtils.transform(signProjects, new Function<SignProjectAuthor, SignProjectListOutput>() {
            @Nullable
            @Override
            public SignProjectListOutput apply(@Nullable SignProjectAuthor input) {
                SignProjectListOutput listOutput = new SignProjectListOutput();
                try {
                    MyBeanUtils.copyBeanNotNull2Bean(input, listOutput);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                listOutput.setApplyNum(input.getApplyNum());

                if (input.getEndTime().getTime() > System.currentTimeMillis()) {
                    if (StringUtils.isNotEmpty(input.getTodayRecordId())) {
                        listOutput.setSignStatus(YesNoStatus.YES.getCode());
                    } else {
                        listOutput.setSignStatus(YesNoStatus.NO_NEW.getCode());
                    }
                } else {
                    listOutput.setSignStatus(3); // 已结束
                }
                return listOutput;
            }
        });
        return listOutputs;
    }

    /**
     * 获取一周数据
     * @return
     */
    public List<Date> getWeekdays() {
        List<Date> dayOfWeeks = Lists.newArrayList();
        Calendar calendar = Calendar.getInstance();
        while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
            calendar.add(Calendar.DATE, -1);
        }
        for (int i = 0; i < 7; i++) {
            dayOfWeeks.add(calendar.getTime());
            calendar.add(Calendar.DATE, 1);
        }
        return dayOfWeeks;
    }

    /**
     * 获取签到项目信息
     * @param id 项目编号
     * @param currentUser 当前用户
     * @return 签到项目
     */
    public SignProjectOutput getDetailXcx(String id, CurrentUser currentUser) {
        SignProjectAuthor signProjectAuthor = signProjectService.getProjectAuthor(id);
        if (null == signProjectAuthor) {
            throw new BusinessException(PartyCode.IS_NO_DATA, "签到项目不存在");
        }
//        signProjectAuthor.setRule(null);
        signProjectAuthor.setShareBackground(null);
        SignProjectOutput signProjectOutput = SignProjectOutput.transform(signProjectAuthor);
        signProjectOutput.setApplyNum(signProjectAuthor.getPassNum());
        if (Strings.isNullOrEmpty(signProjectAuthor.getPublisher())) {
            signProjectOutput.setPublisher(signProjectAuthor.getAuthorName());
            signProjectOutput.setPublisherLogo(signProjectAuthor.getAuthorLogo());
        }
        String filePath = fileBizService.getUploadCIPath(signProjectAuthor.getCreateBy(), "signProject");
        String qrcodeUrl = cosBizService.getPreviewPictureUrl(filePath + signProjectAuthor.getId());
        signProjectOutput.setQrcodeUrl(qrcodeUrl);

        if (null != currentUser) {
            //是否报名
            GroupMember groupMember = signApplyService.get(currentUser.getId(), id);
            if (null == groupMember) {
                signProjectOutput.setApply(false);
            } else {
                signProjectOutput.setApply(true);
                signProjectOutput.setApplyStatus(groupMember.getStatus());
                signProjectOutput.setApplyId(groupMember.getId());

                //今天是否签到
                SignRecord signRecord = signRecordService.getToday(groupMember.getId());
                if (null != signRecord) {
                    signProjectOutput.setSign(true);
                }

                // 累计打卡次数
                Integer signCount = signRecordService.getCount(groupMember.getId());
                signProjectOutput.setSignCount(signCount);

                SignGroup signGroup = signGroupService.get(groupMember.getGroupId());
                if (signGroup != null) {
                    signProjectOutput.setMyGroupId(signGroup.getId());
                    signProjectOutput.setMyGroupName(signGroup.getName());
                }
            }
        } else {
            signProjectOutput.setApply(false);
        }

        //是否在有效时间内
        Date now = new Date();
        if (DateUtils.compareDate(now, signProjectAuthor.getStartTime()) == 1
                && DateUtils.compareDate(signProjectAuthor.getEndTime(), now) == 1) {
            signProjectOutput.setValidTime(true);
        }

        SignGroup signGroup = new SignGroup();
        signGroup.setProjectId(id);
        List<SignGroupListOutput> signGroupList = LangUtils.transform(signGroupService.list(signGroup),
                new Function<SignGroup, SignGroupListOutput>() {
                    @Nullable
                    @Override
                    public SignGroupListOutput apply(@Nullable SignGroup input) {
                        SignGroupListOutput output = new SignGroupListOutput();
                        try {
                            MyBeanUtils.copyBeanNotNull2Bean(input, output);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return output;
                    }
                });
        signProjectOutput.setSignGroups(signGroupList);
        return signProjectOutput;
    }

    public List<SignProjectListOutput> getList(Page page, String memberId) {
        List<SignProject> signProjects = signProjectService.listPage(new SignProject(), page);
        List<SignProjectListOutput> listOutputs = LangUtils.transform(signProjects, new Function<SignProject, SignProjectListOutput>() {
            @Nullable
            @Override
            public SignProjectListOutput apply(@Nullable SignProject input) {
                SignProjectListOutput listOutput = new SignProjectListOutput();
                try {
                    MyBeanUtils.copyBeanNotNull2Bean(input, listOutput);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                listOutput.setApplyNum(input.getApplyNum());

                if (input.getEndTime().getTime() > System.currentTimeMillis()) {
                    GroupMember groupMember = signApplyService.get(memberId, input.getId());
                    if (groupMember != null) {
                        SignRecord today = signRecordService.getToday(groupMember.getId());
                        if (today == null) {
                            listOutput.setSignStatus(YesNoStatus.NO_NEW.getCode());
                        } else {
                            listOutput.setSignStatus(YesNoStatus.YES.getCode());
                        }
                    } else {
                        listOutput.setSignStatus(YesNoStatus.NO_NEW.getCode());
                    }
                } else if (input.getStartTime().getTime() > System.currentTimeMillis()) {
                    listOutput.setSignStatus(4); // 未开始
                } else {
                    listOutput.setSignStatus(3); // 已结束
                }
                return listOutput;
            }
        });
        return listOutputs;
    }


    /**
     * 获取项目的分享背景图片
     *
     * @param projectId 项目id
     * @return
     * @throws Exception
     */
    public String[] getShareBackground(String projectId) throws Exception {
        SignProject signProject = signProjectService.get(projectId);
        if (signProject == null) {
            throw new Exception("项目不存在");
        }
        if (StringUtils.isNotEmpty(signProject.getShareBackground())) {
            String[] picList = signProject.getShareBackground().split(",");
            return picList;
        }
        return new String[]{};
    }

    /**
     * 获取项目规则内容
     *
     * @param projectId 项目id
     * @return
     */
    public String getRuleContent(String projectId) {
        SignProject signProject = signProjectService.get(projectId);
        if (!Strings.isNullOrEmpty(signProject.getRule())) {
            String content = StringEscapeUtils.unescapeHtml4(signProject.getRule());
            signProject.setRule(StringUtils.removeHtmlTag(content));
        }
        return signProject.getRule();
    }

    /**
     * 机构的项目列表
     *
     * @param page  分页
     * @param orgId 机构id
     * @return
     */
    public List<SignProjectListOutput> getOrgProjectList(Page page, String orgId) {
        SignProject signProject = new SignProject();
        //signProject.setCreateBy(orgId);
        List<String> orgIds = memberGroupService.getChildWithMy(orgId);
        signProject.setOrgIds(orgIds);
        List<SignProject> signProjects = signProjectService.listPage(signProject, page);
        List<SignProjectListOutput> projectOutputs = LangUtils.transform(signProjects, new Function<SignProject, SignProjectListOutput>() {
            @Nullable
            @Override
            public SignProjectListOutput apply(@Nullable SignProject input) {
                SignProjectListOutput signProjectOutput = new SignProjectListOutput();
                try {
                    MyBeanUtils.copyBeanNotNull2Bean(input, signProjectOutput);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (input.getStartTime().getTime() > System.currentTimeMillis()) {
                    signProjectOutput.setIsProgress(2);
                } else if (input.getEndTime().getTime() < System.currentTimeMillis()) {
                    signProjectOutput.setIsProgress(YesNoStatus.NO.getCode());
                } else {
                    signProjectOutput.setIsProgress(YesNoStatus.YES.getCode());
                }
                String filePath = fileBizService.getUploadCIPath(input.getCreateBy(), "signProject");
                String qrCodeUrl = cosBizService.getPreviewPictureUrl(filePath + input.getId());
                signProjectOutput.setQrCodeUrl(qrCodeUrl);
                return signProjectOutput;
            }
        });
        return projectOutputs;
    }
}
